﻿using System;
using System.IO;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace HideWindows
{
    public partial class Form1 : Form
    {
        private string CONFIG_FILE =Application.StartupPath+ "\\exelist.cfg";
        private string HOTKEY_FILE = Application.StartupPath + "\\hotkey.cfg";
        private Keys currentHotkey = Keys.None;
        private bool isCtrl, isAlt, isShift;
        private int hotkeyId = 1;

        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);

        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll")]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll")]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        [DllImport("user32.dll")]
        private static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        [DllImport("user32.dll")]
        private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

        private const int MOD_ALT = 0x1;
        private const int MOD_CONTROL = 0x2;
        private const int MOD_SHIFT = 0x4;
        private const int SW_HIDE = 0;
        private const int SW_SHOW = 5;

        private const int WH_MOUSE_LL = 14;
        private const int WM_LBUTTONDOWN = 0x0201;
        private const int WM_RBUTTONDOWN = 0x0204;
        private const int WM_LBUTTONUP = 0x0202;
        private const int WM_RBUTTONUP = 0x0205;

        private bool processesHidden = false;
        private Dictionary<string, List<IntPtr>> hiddenProcesses = new Dictionary<string, List<IntPtr>>();
        private Dictionary<string, IntPtr> showProcesses = new Dictionary<string,IntPtr>();
        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
        private LowLevelMouseProc _mouseProc;
        private IntPtr _mouseHookID = IntPtr.Zero;
        private bool _leftButtonDown = false;
        private bool _rightButtonDown = false;

        public Form1()
        {
            InitializeComponent();

            // 确保创建窗口句柄
            if (!IsHandleCreated)
            {
                CreateHandle();
            }

            // 创建托盘图标的上下文菜单
            ContextMenuStrip contextMenu = new ContextMenuStrip();
            ToolStripMenuItem exitItem = new ToolStripMenuItem("退出");
            exitItem.Click += (s, e) => 
            {
                Application.Exit();
            };
            contextMenu.Items.Add(exitItem);
            
            notifyIcon.ContextMenuStrip = contextMenu;
            
            LoadConfig();
            LoadHotkeyConfig();
            LoadAutoStartConfig();

            listBoxExes.DrawMode = DrawMode.OwnerDrawFixed;
            listBoxExes.DrawItem += listBoxExes_DrawItem;

            System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
            timer.Interval = 2000; // 修改为500毫秒
            timer.Tick += (s, e) => UpdateListItemColors();
            timer.Start();

            // 添加启动延时最小化定时器
            System.Windows.Forms.Timer startupTimer = new System.Windows.Forms.Timer();
            startupTimer.Interval = 200; // 修改为500毫秒
            startupTimer.Tick += (s, e) =>
            {
                this.WindowState = FormWindowState.Minimized;
                this.Hide();
                this.ShowInTaskbar = false;
                notifyIcon.Visible = true;
                notifyIcon.Icon = Properties.Resources.main;
                startupTimer.Stop(); // 确保定时器只执行一次
                startupTimer.Dispose(); // 清理定时器
            };
            startupTimer.Start();

            // 添加鼠标钩子
            _mouseProc = HookCallback;
            _mouseHookID = SetHook(_mouseProc);
        }

        private IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                switch ((int)wParam)
                {
                    case WM_LBUTTONDOWN:
                        _leftButtonDown = true;
                        break;
                    case WM_RBUTTONDOWN:
                        _rightButtonDown = true;
                        break;
                    case WM_LBUTTONUP:
                        _leftButtonDown = false;
                        break;
                    case WM_RBUTTONUP:
                        _rightButtonDown = false;
                        break;
                }

                // 当左键和右键同时按下时触发
                if (_leftButtonDown && _rightButtonDown)
                {
                    ToggleProcessesVisibility();
                    // 重置按键状态
                    _leftButtonDown = false;
                    _rightButtonDown = false;
                }
            }
            return CallNextHookEx(_mouseHookID, nCode, wParam, lParam);
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.ShowInTaskbar = false;
                notifyIcon.Visible = true;
                notifyIcon.ShowBalloonTip(1000, "提示", 
                    "程序已最小化到系统托盘，双击图标可以恢复。", 
                    ToolTipIcon.Info);
            }
        }

        private void notifyIcon_DoubleClick(object sender, EventArgs e)
        {
            this.Show();
            this.ShowInTaskbar = true;
            this.WindowState = FormWindowState.Normal;
            this.Activate();
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;  // 取消关闭操作
                this.WindowState = FormWindowState.Minimized;
                this.Hide();
                this.ShowInTaskbar = false;
                notifyIcon.Visible = true;
                return;
            }

            // 如果是应用程序退出，则清理资源
            if (notifyIcon != null)
            {
                notifyIcon.Visible = false;
                notifyIcon.Dispose();
            }
            UnregisterHotKey(this.Handle, hotkeyId);

            // 清理鼠标钩子
            if (_mouseHookID != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_mouseHookID);
                _mouseHookID = IntPtr.Zero;
            }
            
            base.OnFormClosing(e);
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "可执行文件 (*.exe)|*.exe|所有文件 (*.*)|*.*";
                openFileDialog.FilterIndex = 1;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    if (!listBoxExes.Items.Contains(openFileDialog.FileName))
                    {
                        listBoxExes.Items.Add(openFileDialog.FileName);
                        SaveConfig();
                    }
                }
            }

            UpdateListItemColors();
        }

        private void LoadConfig()
        {
            if (File.Exists(CONFIG_FILE))
            {
                try
                {
                    string[] lines = File.ReadAllLines(CONFIG_FILE);
                    listBoxExes.Items.AddRange(lines);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"加载配置文件失败: {ex.Message}", "错误", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            UpdateListItemColors();
        }

        private void SaveConfig()
        {
            try
            {
                string[] exeList = new string[listBoxExes.Items.Count];
                listBoxExes.Items.CopyTo(exeList, 0);
                File.WriteAllLines(CONFIG_FILE, exeList);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存配置文件失败: {ex.Message}", "错误", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (listBoxExes.SelectedItems.Count > 0)
            {
                var result = MessageBox.Show(
                    "确定要删除选中的项目吗？", 
                    "确认删除",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question);

                if (result == DialogResult.Yes)
                {
                    while (listBoxExes.SelectedItems.Count > 0)
                    {
                        listBoxExes.Items.Remove(listBoxExes.SelectedItems[0]);
                    }
                    SaveConfig(); // 删除后自动保存配置
                }
            }
            else
            {
                MessageBox.Show("请先选择要删除的项目", "提示", 
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            UpdateListItemColors();
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            ToggleProcessesVisibility();
        }

        private void UpdateListItemColors()
        {
            var selectedIndices = listBoxExes.SelectedIndices;
            
            listBoxExes.DrawMode = DrawMode.OwnerDrawFixed;
            listBoxExes.Refresh();
            
            foreach (int index in selectedIndices)
            {
                listBoxExes.SetSelected(index, true);
            }
        }

        private void listBoxExes_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (e.Index < 0) return;

            string exePath = listBoxExes.Items[e.Index].ToString();
            string exeName = Path.GetFileNameWithoutExtension(exePath);
            Process[] processes = Process.GetProcessesByName(exeName);
            bool isHidden = hiddenProcesses.ContainsKey(exePath);
            bool isRunning = processes.Length > 0;

            Color textColor;
            if (isHidden)
            {
                textColor = Color.Gray;
            }
            else if (!isRunning)
            {
                textColor = Color.Black;
            }
            else
            {
                textColor = Color.Blue;
            }

            e.DrawBackground();

            using (Brush brush = new SolidBrush(textColor))
            {
                e.Graphics.DrawString(exePath, e.Font, brush, e.Bounds);
            }

            if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
            {
                e.DrawFocusRectangle();
            }
        }

        private void LoadAutoStartConfig()
        {
            try
            {
                Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
                    @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
                
                if (key != null)
                {
                    string value = (string)key.GetValue(Application.ProductName);
                    chkAutoStart.Checked = value != null && 
                        value.Equals($"\"{Application.ExecutablePath}\" -minimized", 
                        StringComparison.OrdinalIgnoreCase);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"读取自启动配置失败: {ex.Message}", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void chkAutoStart_Click(object sender, EventArgs e)
        {
            try
            {
                Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
                    @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
                
                if (key != null)
                {
                    if (chkAutoStart.Checked)
                    {
                        // 添加开机启动项，带上最小化参数
                        key.SetValue(Application.ProductName, 
                            $"\"{Application.ExecutablePath}\" -minimized");
                    }
                    else
                    {
                        // 移除开机动项
                        key.DeleteValue(Application.ProductName, false);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"设置自启动失败: {ex.Message}", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                chkAutoStart.Checked = !chkAutoStart.Checked; // 恢复选中状态
            }
        }

        protected override void WndProc(ref Message m)
        {
            const int WM_HOTKEY = 0x0312;
            
            try
            {
                if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == hotkeyId)
                {
                    ToggleProcessesVisibility();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"处理热键消息时出错: {ex.Message}", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
            base.WndProc(ref m);
        }

        private void txtHotkey_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                UnregisterHotKey(this.Handle, hotkeyId);
            }
            catch
            { 
            }
            e.SuppressKeyPress = true;
            
            isCtrl = e.Control;
            isAlt = e.Alt;
            isShift = e.Shift;
            currentHotkey = e.KeyCode;
            
            UpdateHotkeyText();
        }

        private void txtHotkey_KeyUp(object sender, KeyEventArgs e)
        {
            if (currentHotkey != Keys.None)
            {
                SaveHotkeyConfig();
            }
        }

        private void UpdateHotkeyText()
        {
            string hotkeyText = "";
            if (isCtrl) hotkeyText += "Ctrl + ";
            if (isAlt) hotkeyText += "Alt + ";
            if (isShift) hotkeyText += "Shift + ";
            if (currentHotkey != Keys.None)
                hotkeyText += currentHotkey.ToString();
            
            txtHotkey.Text = hotkeyText;
        }

        private void RegisterNewHotkey()
        {
            try
            {
                // 先注销之前的热键
                UnregisterHotKey(this.Handle, hotkeyId);

                int modifiers = 0;
                if (isCtrl) modifiers |= MOD_CONTROL;
                if (isAlt) modifiers |= MOD_ALT;
                if (isShift) modifiers |= MOD_SHIFT;

                if (currentHotkey != Keys.None)
                {
                    if (!RegisterHotKey(this.Handle, hotkeyId, modifiers, (int)currentHotkey))
                    {
                        throw new Exception("热键注册失败，可能与其他程序冲突");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"注册热键失败: {ex.Message}", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                
                // 清除热键设置
                currentHotkey = Keys.None;
                isCtrl = isAlt = isShift = false;
                UpdateHotkeyText();
            }
        }

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            // 窗口句柄创建后重新注册热键
            if (currentHotkey != Keys.None)
            {
                RegisterNewHotkey();
            }
        }

        private void LoadHotkeyConfig()
        {
            if (File.Exists(HOTKEY_FILE))
            {
                try
                {
                    string[] lines = File.ReadAllLines(HOTKEY_FILE);
                    if (lines.Length >= 4)
                    {
                        isCtrl = bool.Parse(lines[0]);
                        isAlt = bool.Parse(lines[1]);
                        isShift = bool.Parse(lines[2]);
                        currentHotkey = (Keys)Enum.Parse(typeof(Keys), lines[3]);
                        
                        UpdateHotkeyText();
                        RegisterNewHotkey();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"加载快捷键配置失败: {ex.Message}", "错误",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void btnApplyHotKeys_Click(object sender, EventArgs e)
        {
            RegisterNewHotkey();
        }

        private void SaveHotkeyConfig()
        {
            try
            {
                string[] lines = new string[]
                {
                    isCtrl.ToString(),
                    isAlt.ToString(),
                    isShift.ToString(),
                    currentHotkey.ToString()
                };
                File.WriteAllLines(HOTKEY_FILE, lines);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存快捷键配置失败: {ex.Message}", "错误",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void ToggleProcessesVisibility()
        {
            if (!processesHidden)
            {
                // 隐藏进程
                int hiddenCount = 0;
                hiddenProcesses.Clear();
                foreach (string exePath in listBoxExes.Items)
                {
                    string exeName = Path.GetFileName(exePath);
                    Process[] processes = Process.GetProcessesByName(
                        Path.GetFileNameWithoutExtension(exeName));

                    List<IntPtr> handles = new List<IntPtr>();
                    foreach (Process proc in processes)
                    {
                        // 使用 EnumWindows 来查找窗口句柄
                        EnumWindows((hWnd, lParam) =>
                        {
                            uint processId;
                            GetWindowThreadProcessId(hWnd, out processId);
                            if (processId == (uint)proc.Id && IsWindowVisible(hWnd))
                            {
                                ShowWindow(hWnd, SW_HIDE); // 显示窗口
                                handles.Add(hWnd);
                                hiddenCount++;
                            }
                            return true; // 继续枚举
                        }, IntPtr.Zero);
                        //if (proc.MainWindowHandle != IntPtr.Zero)
                        //{
                        //    ShowWindow(proc.MainWindowHandle, SW_HIDE);
                        //    handles.Add(proc.MainWindowHandle);
                        //    hiddenCount++;
                        //}
                    }
                    if (handles.Count > 0)
                    {
                        hiddenProcesses[exePath] = handles;
                    }
                }
                if (hiddenCount > 0)
                {
                    this.Text = $"进程隐藏工具 - 已隐藏{hiddenCount}个窗口";
                }
                else
                {
                   // MessageBox.Show("没有找到可以隐藏的进程窗口", "提示",MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }
            else
            {

                //显示隐藏的进程
                foreach (var handles in hiddenProcesses.Values)
                {
                    foreach (IntPtr handle in handles)
                    {
                        ShowWindow(handle, SW_SHOW);
                    }
                }
                hiddenProcesses.Clear();
                this.Text = "进程隐藏工具";
            }
              
            processesHidden = !processesHidden;
            UpdateListItemColors();

        }

        private void btnShowHW_Click(object sender, EventArgs e)
        {
            if (!processesHidden && hiddenProcesses.Count==0)
            {
                if (showProcesses.ContainsKey(cmbTitle.Text))
                {
                    ShowWindow(showProcesses[cmbTitle.Text], SW_SHOW);
                }
            }
        }
        private void listBoxExes_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbTitle.Items.Clear();
            showProcesses.Clear();
            string exeName = Path.GetFileNameWithoutExtension(listBoxExes.Text);
            Process[] processes = Process.GetProcessesByName(exeName);

            foreach (Process proc in processes)
            {
                // 使用 EnumWindows 来查找窗口句柄
                EnumWindows((hWnd, lParam) =>
                {
                    uint processId;
                    GetWindowThreadProcessId(hWnd, out processId);
                    string GetTitle = GetWindowTitle(hWnd);
                    if (processId == (uint)proc.Id && GetTitle != null)
                    {
                        cmbTitle.Items.Add(GetTitle);
                        showProcesses[GetTitle]= hWnd;
                    }
                    return true; // 继续枚举
                }, IntPtr.Zero);
            }
        }

        private void ShowAllHideWindows()
        {
            foreach (string exePath in listBoxExes.Items)
            {
                string exeName = Path.GetFileNameWithoutExtension(exePath);
                Process[] processes = Process.GetProcessesByName(exeName);

                foreach (Process proc in processes)
                {
                    // 使用 EnumWindows 来查找窗口句柄
                    EnumWindows((hWnd, lParam) =>
                    {
                        uint processId;
                        GetWindowThreadProcessId(hWnd, out processId);
                        if (processId == (uint)proc.Id && GetWindowTitle(hWnd) != null)
                        {
                            ShowWindow(hWnd, SW_SHOW); // 显示窗口
                            return false;
                        }
                        return true; // 继续枚举
                    }, IntPtr.Zero);
                }
            }
        }
        private string GetWindowTitle(IntPtr hWnd)
        {
            const int nChars = 256;
            StringBuilder Buff = new StringBuilder(nChars);
            if (GetWindowText(hWnd, Buff, nChars) > 0)
            {
                return Buff.ToString();           
            }
            return null;
        }
    }
}
